import React, { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import {
  AutoComplete,
  Box,
  FormStatusMessage,
  MainButton,
  makeToast,
  Radio,
  Text,
  ThemeColorType,
} from '@nova-hf/ui';
import { OptionsType } from '@nova-hf/ui/umd/ts/src/form-elements/react-select-components/ReactSelectWrapper';
import useCompleteOrder from 'beta/pages/thjonustur/[serviceId]/skref/hooks/useCompleteOrder';
import { useTranslation } from 'beta/utils/i18n';
import { useRouter } from 'next/router';
import {
  ReasonsForCancellingContractOrder_CfContent,
  useCancelContractMutation,
  useContractQuery,
  useCustomerIsCompanyQuery,
  useReasonsForCancelQuery,
  WhenToApply,
} from 'typings/graphql';

import ApplicableProducts from './ApplicableProducts';

export type ProductVariants = {
  id: string;
  variant: string;
  serviceId: string;
  validVariant?: boolean;
};
type CancelContractForm = {
  contractId: string;
  whenToApplyText: WhenToApply;
  reason: string;
};

type ConfirmCancellationProps = {
  contractId: string;
  color: ThemeColorType;
};

const ConfirmCancellation = ({ contractId, color }: ConfirmCancellationProps) => {
  const router = useRouter();
  const { t } = useTranslation(['alltSaman', 'errors']);
  const customerId = (router.query.customerId as string) ?? '';
  const [cancelReasonOptions, setCancelReasonOptions] = useState<OptionsType[]>();
  const [selectedOption, setSelectedOption] = useState('');
  const [cancelContractMutation] = useCancelContractMutation();
  const { data: isCompanyData } = useCustomerIsCompanyQuery({
    variables: {
      input: { id: customerId },
    },
  });
  const { control, watch, handleSubmit, setValue } = useForm<CancelContractForm>({
    defaultValues: {
      contractId: '',
      whenToApplyText: undefined,
      reason: '',
    },
    mode: 'onChange',
    delayError: 500,
  });
  const watchFields = watch();

  const { data: contractData } = useContractQuery({
    variables: {
      input: {
        id: contractId,
      },
    },
  });

  const contractItems = contractData?.contract?.contractItems;
  const serviceId = contractData?.contract?.contractItems[0].serviceId ?? '';
  const [selected, setSelected] = useState<ProductVariants[]>([]);
  const { onSubmit, orderError, addToCartError } = useCompleteOrder(
    watchFields.whenToApplyText,
    serviceId,
    customerId,
    [...(selected ? selected : [])],
  );

  const selectedProd = (prod: ProductVariants) => {
    const filterSelected = selected.filter((s) => s.serviceId !== prod.serviceId);

    prod.validVariant
      ? setSelected([
          ...filterSelected,
          {
            id: prod.id,
            variant: prod.variant,
            serviceId: prod.serviceId,
            validVariant: prod.validVariant,
          },
        ])
      : setSelected(filterSelected);
  };
  const cancelSubmit = async () => {
    try {
      onSubmit();
      await cancelContractMutation({
        variables: {
          input: {
            id: contractId,
            whenToApply: watchFields.whenToApplyText,
            reason: watchFields.reason,
          },
        },
      });
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger('cancelContract.errorTitle', error.message);
      }
    }
  };
  const { error } = useReasonsForCancelQuery({
    variables: {
      order: ReasonsForCancellingContractOrder_CfContent.OrderAsc,
    },
    onCompleted: (data) => {
      if (data.reasonsForCancellingContractCollection?.items.length) {
        const mappedOptions: OptionsType[] = data.reasonsForCancellingContractCollection.items.map(
          (select) => {
            return {
              value: select?.id || '',
              label: select?.reason || '',
            };
          },
        );
        setCancelReasonOptions(mappedOptions);
      }
    },
  });

  useEffect(() => {
    if (orderError) makeToast.danger(t('toast.createOrderError'), orderError.message ?? '');
    if (addToCartError) makeToast.danger(t('toast.addingCartError'), addToCartError.message ?? '');
  }, [orderError, addToCartError]);

  if (error) {
    makeToast.danger(t('cancelContract.error'), error.message ?? '');
  }
  return (
    <>
      <Box marginBottom={10}>
        <Text variant="h5" marginBottom={4}>
          {t('cancelContract.subtitle')}
        </Text>
        <Text variant="pMediumRegular" marginBottom={4}>
          {t('cancelContract.description')}
        </Text>
        <Box marginBottom={6}>
          <Text variant="pLargeBold" marginBottom={3}>
            {t('cancelContract.reasonInfo')}
          </Text>
          <Controller
            name="reason"
            control={control}
            rules={{ required: true }}
            render={({ field }) => {
              const { value } = field;
              const findValue = cancelReasonOptions?.find((option) => {
                option.value === value;
              });
              setSelectedOption(value);
              return (
                <AutoComplete
                  options={
                    cancelReasonOptions ?? [{ value: 'onnur-astaeda', label: 'Önnur ástæða' }]
                  }
                  label={t('cancelContract.reason')}
                  id="reasonForCancel"
                  placeholder={t('cancelContract.autocompletePlaceholder')}
                  onChange={(option) => option?.value && setValue('reason', option.value)}
                  value={findValue}
                  renderAs="select"
                  isSearchable={false}
                  isClearable={false}
                />
              );
            }}
          />
        </Box>
        <Box>
          {contractItems?.map((contractItem) => (
            <Box key={contractItem.id}>
              <ApplicableProducts
                contractItem={contractItem}
                isCustomerCompany={isCompanyData?.customer?.isCompany ?? false}
                color={color}
                setSelected={selectedProd}
                reason={selectedOption}
              />
            </Box>
          ))}
        </Box>
      </Box>
      <Box
        renderAs="form"
        onSubmit={handleSubmit(cancelSubmit)}
        display="flex"
        flexDirection="column"
        width="100%"
        marginTop={[5, 8]}
      >
        <Box>
          <Text variant="pLargeBold" marginBottom={4}>
            {t('cancelContract.whenToApply')}
          </Text>
        </Box>
        <Box display="flex" flexDirection={['column', 'column', 'row']} gap={4} marginBottom={12}>
          <Controller
            name="whenToApplyText"
            control={control}
            rules={{ required: true }}
            render={({ field }) => {
              const { value, onChange } = field;
              return (
                <>
                  <Radio
                    isChecked={value === WhenToApply.Immediate}
                    value={t('cancelContract.dateRightNow')}
                    color={color}
                    onChange={() => onChange(WhenToApply.Immediate)}
                  />
                  <Radio
                    isChecked={value === WhenToApply.StartOfNextCycle}
                    value={t('cancelContract.dateNextCycle')}
                    color={color}
                    onChange={() => onChange(WhenToApply.StartOfNextCycle)}
                  />
                </>
              );
            }}
          />
        </Box>
        <Box display="flex" width="100%" flexDirection={{ sm: 'column', md: 'row' }}>
          <Box display="flex" justifyContent="flex-start" width="50%" alignItems="center">
            {watchFields.whenToApplyText === WhenToApply.Immediate && (
              <Box width="8/12">
                <FormStatusMessage message={t('cancelContract.warning')} status="warning" />
              </Box>
            )}
          </Box>
          <Box display="flex" width={{ sm: '100%', md: '4/12' }} marginLeft="auto">
            <MainButton
              text={t('cancelContract.submitButton')}
              icon="longArrowRight"
              colorScheme={'orange'}
              dottedShadow="none"
              isSubmitButton
              isDisabled={!watchFields.whenToApplyText || !watchFields.reason}
            />
          </Box>
        </Box>
      </Box>
    </>
  );
};

export default ConfirmCancellation;
